// express中间件
// 对请求进行预处理

// 如何区分中间件？路由？
// next()函数
// next()函数的作用是将控制权交给下一个中间件，如果没有next()函数，则请求会卡在当前中间件，不会继续往下执行

// 如何区分中间件是局部还是全局
// 如果在app.use()中使用，则是全局中间件，如果是在路由中使用，则是局部中间件

// 中间件的作用
// 1. 执行任何代码
// 2. 修改请求和响应对象
// 3. 终结请求-响应循环
// 4. 调用堆栈中的下一个中间件

// 中间件的分类
// 1. 应用级别的中间件
// 2. 路由级别的中间件
// 3. 错误级别的中间件
// 4. 内置中间件
// 5. 第三方中间件

// 应用级别的中间件
// app.use((req, res, next) => {
//     console.log('这是一个应用级别的中间件');
//     next();
// });

// 路由级别的中间件
// app.get('/', (req, res, next) => {
//     console.log('这是一个路由级别的中间件');
//     next();
// });

// 错误级别的中间件
// app.use((err, req, res, next) => {
//     console.log('这是一个错误级别的中间件');
//     next();
// });

// 内置中间件
// 静态资源
// app.use(express.static('public'));
// 解析json请求体
// app.use(express.json());
// 解析urlencoded请求体
// app.use(express.urlencoded({ extended: false }));

// 第三方中间件
// body-parser
// npm i body-parser

// 中间件的执行顺序
// 1. 从上到下依次执行
// 2. 如果有next()函数，则执行下一个中间件
// 3. 如果没有next()函数，则请求会卡在当前中间件，不会继续往下执行

const express = require("express");
const app = express();

//内置中间件
app.use(express.static("public"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

//全局中间件
app.use((req, res, next) => {
  console.log("这是一个应用级别的中间件1");
  req.name = "张三";
  next();
});

app.use((req, res, next) => {
  console.log("这是一个应用级别的中间件2");
  req.age = 18;
  next();
});

app.get("/user", (req, res) => {
  res.send("Hello Admin！" + "我是" + req.name + "，今年" + req.age + "岁");
});

//局部中间件
const mw = (req, res, next) => {
  console.log("这是一个路由级别的中间件1");
  req.name = "admin";
  next();
};

const mw1 = (req, res, next) => {
  console.log("这是一个路由级别的中间件2");
  req.age = 28;
  next();
};

app.get("/admin", mw, mw1, (req, res) => {
  res.send("Hello 张三！" + "我是" + req.name + "，今年" + req.age + "岁");
});

//演示错误中间件
app.get("/", (req, res) => {
  console.log("这是一个错误中间件");
  throw new Error("系统错误");
});

//演示内置中间件json
app.post("/json", (req, res) => {
  console.log(req.body);
  res.send("Hello!" + "我是" + req.body.name + "，今年" + req.body.age + "岁");
});

//演示内置中间件urlencoded
app.post("/urlencoded", (req, res) => {
  console.log(req.body);
  res.send("Hello!" + "我是" + req.body.name + "，今年" + req.body.age + "岁");
});

//演示第三方中间件body-parser
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post("/body-parser", (req, res) => {
  console.log(req.body);
  res.send("Hello!" + "我是" + req.body.name + "，今年" + req.body.age + "岁");
});

//错误中间件
app.use((err, req, res, next) => {
  res.send("error" + err.message);
});

app.listen(3000, () => {
  console.log("服务器已启动");
});
